# !/usr/bin/env python3
# -*- coding: utf-8 -*-
from neo4j import get_neo4j_connect
from server.config import neo4j_url, neo4j_user_name, neo4j_password

# TODO: 这个连接目前是全局的, 之后或许可以做成一个线程池
graph = get_neo4j_connect(neo4j_url, neo4j_user_name, neo4j_password, True, 5)


def get_property(entity):
    """
    属性查询
    :param entity:
    :return:
    """
    cursor = graph.run('match(n {office_name:{a}})return n', a=entity)
    cursor.forward()
    record = cursor.current()
    return dict(record['n'])


def get_relation(entity, rel_type):
    """
    关系查询，直接关联
    :param entity:
    :param rel_type:
    :return:
    """
    cursor = graph.run(
        'match(n {office_name:{a}})-[]->(b {type:{r}}) return b',
        a=entity,
        r=rel_type
    )

    ans = []
    while cursor.forward():
        record = cursor.current()
        ans.append(dict(record['b']))

    return ans


def get_relation_mul(entity, rel_type):
    """
    关系查询，多级关联，最多两跳
    :param entity:
    :param rel_type:
    :return:
    """
    cursor = graph.run(
        'match(n {office_name:{a}})-[*..2]->(b {type:{r}}) return b',
        a=entity, r=rel_type
    )

    ans = []
    while cursor.forward():
        record = cursor.current()
        ans.append(dict(record['b']))
        # print(dict(record['b']))
    return ans


def get_relation_triple(entity, rel_type):
    """
    关系查询，多级关联，最多三跳
    :param entity:
    :param rel_type:
    :return:
    """
    cursor = graph.run(
        'match(n {office_name:{a}})-[*..3]->(b {type:{r}}) return b',
        a=entity,
        r=rel_type
    )

    ans = []
    while cursor.forward():
        record = cursor.current()
        ans.append(dict(record['b']))
        # print(dict(record['b']))
    return ans


def get_reverse_relation(entity, rel_type):
    """
    逆向关系查询 直接关联
    :param entity:
    :param rel_type:
    :return:
    """
    cursor = graph.run(
        'match(n {office_name:{a}})<-[]-(b {type:{r}}) return b', a=entity,
        r=rel_type)
    # cursor = cls.graph.run(
    #   'match(n{office_name: '数字共享空间'})
    #   < -[] - (b {type:'资源'})return b'
    # )

    ans = []
    while cursor.forward():
        record = cursor.current()
        ans.append(dict(record['b']))
        # print(dict(record['b']))
    return ans


def get_reverse_relation_mul(entity, rel_type):
    """
    逆向关系查询 多级关联 最多两跳
    :param entity:
    :param rel_type:
    :return:
    """
    # print(entity,type)
    cursor = graph.run(
        'match(n {office_name:{a}})<-[*..2]-(b {type:{r}}) return b',
        a=entity, r=rel_type)
    # cursor = cls.graph.run(
    # 'match(n {office_name:{a}})<-[*]-(b {type:{r}}) return b',
    # a='总馆北区', r='资源'
    # )

    ans = []
    while cursor.forward():
        record = cursor.current()
        ans.append(dict(record['b']))
        # print(dict(record['b']))
    return ans


def get_entity(what_type):
    """
    得到某个类型的所有实体
    :param what_type:
    :return:
    """
    # print(entity,type)
    cursor = graph.run('match(n {type:{a}}) return n', a=what_type)
    # cursor = cls.graph.run(
    # 'match(n {office_name:{a}})<-[*]-(b {type:{r}})
    # return b', a='总馆北区', r='资源'
    # )
    ans = []
    while cursor.forward():
        record = cursor.current()
        ans.append(dict(record['n']))
    return ans


def get_entity_for_kind(what_type, att):
    """
    得到某个类型具有某一kind属性的所有实体
    :param what_type:
    :param att:
    :return:
    """
    cursor = graph.run(
        'match (n) where n.type={a} and n.kind={b} return n',
        a=what_type, b=att)
    # cursor = cls.graph.run(
    # 'match(n {office_name:{a}})<-[*]-(b {type:{r}}) return b',
    # a='总馆北区', r='资源'
    # )
    ans = []
    while cursor.forward():
        record = cursor.current()
        ans.append(dict(record['n']))
    return ans


# 特定任务查询
# 馆藏分布查询：通过资源查找对应的馆室，再通过资源查找对应的资源类别
def get_area_resource_type(what_area):
    cursor = graph.run(
        "match (b {type:'资源类型'})<-[]-(a {type:'资源'})-[*2]->"
        "(n {office_name:{a}}) return b",
        a=what_area
    )
    ans = []
    while cursor.forward():
        record = cursor.current()
        if dict(record['b']) not in ans:
            ans.append(dict(record['b']))
    return ans
